<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <title>springcloud之OpenFeign | rongshen</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  
  
  
<link rel="stylesheet" href="/css/style.css">

  
    
<link rel="stylesheet" href="/css/highlight.css">

  
  <meta name="description" content="springcloud学习笔记，第五章，OpenFeign服务调用">
<meta property="og:type" content="article">
<meta property="og:title" content="springcloud之OpenFeign">
<meta property="og:url" content="http://example.com/2020/09/27/springcloud%E4%B9%8BOpenFeign/index.html">
<meta property="og:site_name" content="rongshen">
<meta property="og:description" content="springcloud学习笔记，第五章，OpenFeign服务调用">
<meta property="og:locale" content="en_US">
<meta property="og:image" content="http://cdn.rongshen2020.com/2020927a1.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/2020927a2.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/2020927a3.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/2020927a4.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/2020927a5.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/2020927a6.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/2020927a7.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/2020927a8.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/2020927a9.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/2020927a10.png">
<meta property="article:published_time" content="2020-09-27T02:36:57.000Z">
<meta property="article:modified_time" content="2021-05-07T06:48:54.204Z">
<meta property="article:author" content="John Doe">
<meta property="article:tag" content="springCloud">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://cdn.rongshen2020.com/2020927a1.png"><meta name="generator" content="Hexo 6.1.0"></head>

<body>
  <div id="wrapper">
    <header id="header">
  <h1 id="title">
    <a href="/">rongshen</a>
  </h1>
  <nav>
    
    
      
      <a class="nav-link" href="/">Home</a>
    
      
        <span class="nav-spacer">×</span>
      
      <a class="nav-link" href="/archives">Archives</a>
    
      
        <span class="nav-spacer">×</span>
      
      <a class="nav-link" target="_blank" rel="noopener" href="https://github.com/Aaron-boom">Github</a>
    
      
        <span class="nav-spacer">×</span>
      
      <a class="nav-link" href="/2020/04/13/About-Me/">About</a>
    
    
  </nav>
</header>

    <div id="content">
      <article id="post-springcloud之OpenFeign" class="article article-type-post" itemprop="blogPost" itemscope>
  <div class="article-inner">
    
      <header class="article-header">
        
  
    <h2 class="article-title" itemprop="headline name">
      springcloud之OpenFeign
    </h2>
  


        <div class="article-meta">
          <time class="article-date" datetime="2020-09-27T02:36:57.000Z" itemprop="datePublished">2020-09-27</time>

          
        </div>
      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
      
        <blockquote>
<p>springcloud学习笔记，第五章，OpenFeign服务调用</p>
</blockquote>
<span id="more"></span>


<h2 id="简介："><a href="#简介：" class="headerlink" title="简介："></a>简介：</h2><ul>
<li><p>feign翻译：v.假装，装作，佯装(有某种感觉或生病、疲倦等)</p>
</li>
<li><p>feign已经停止更新了，openFeign成为替代。</p>
<p>feign是一个声明式webService客户端。使用feign能让编写的web service客户端更加简单。它的使用方法是定义一个服务接口，在上面添加注解。</p>
</li>
<li><p>feign让微服务之间的调用变得更简单了，类似controller调用service。Spring Cloud集成了Ribbon和Eureka，可在使用Feign时提供负载均衡的http客户端。</p>
<p>主要是利用了OpenFeign的声明式方式定义Web服务客户端；其次，通过集成Ribbon或Eureka实现负载均衡的HTTP客户端。</p>
</li>
</ul>
<h2 id="Feign能干什么？"><a href="#Feign能干什么？" class="headerlink" title="Feign能干什么？"></a>Feign能干什么？</h2><p><img src="http://cdn.rongshen2020.com/2020927a1.png"></p>
<h3 id="Feign与OpenFeign的区别："><a href="#Feign与OpenFeign的区别：" class="headerlink" title="Feign与OpenFeign的区别："></a>Feign与OpenFeign的区别：</h3><p><img src="http://cdn.rongshen2020.com/2020927a2.png"></p>
<h2 id="OpenFeign使用示例："><a href="#OpenFeign使用示例：" class="headerlink" title="OpenFeign使用示例："></a>OpenFeign使用示例：</h2><p>总体模块：</p>
<p><img src="http://cdn.rongshen2020.com/2020927a3.png"></p>
<p><strong>解释：</strong>两个服务生产者provider，一个消费者。eureka继续作为服务注册中心。</p>
<p>provider生产者模块没有特别之处，重点在consumer消费者模块。</p>
<h3 id="consumer消费者模块："><a href="#consumer消费者模块：" class="headerlink" title="consumer消费者模块："></a>consumer消费者模块：</h3><ul>
<li>Feign是在消费端调用的。rest风格的client端，也就是消费侧。</li>
</ul>
<ol>
<li><p>POM依赖：</p>
<pre><code class="java"> &lt;!--openFeign--&gt;
     &lt;dependency&gt;
         &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
         &lt;artifactId&gt;spring-cloud-starter-openfeign&lt;/artifactId&gt;
     &lt;/dependency&gt;
</code></pre>
</li>
<li><p>YML：</p>
<pre><code class="java">server:
  port: 80

spring:
  application:
    name: cloud-order-service

eureka:
  client:
    register-with-eureka: false #表示是否将自己注册进eureka,本consumer不需要注册
    fetch-registry: true #这是貌似不是关键点，表示从eureka中获取服务的注册信息
    service-url:
      defaultZone: http://localhost:7001/eureka
</code></pre>
</li>
<li><p>主启动类，添加注解<code>@EnableFeignClients</code></p>
</li>
<li><p>业务类：</p>
<p><img src="http://cdn.rongshen2020.com/2020927a4.png"></p>
<ol>
<li><p>controller：</p>
<pre><code class="java">@RestController
@Slf4j
public class OrderFeignController &#123;

    @Resource
    private PaymentFeignService paymentFeignService;

    @GetMapping(value = &quot;/consumer/payment/get/&#123;id&#125;&quot;)
    public CommonResult&lt;Payment&gt; getPaymentById(@PathVariable(&quot;id&quot;) Long id) &#123;
        return paymentFeignService.getPaymentById(id);
    &#125;
&#125;
</code></pre>
</li>
<li><p>service：</p>
<pre><code class="java">@Component
@FeignClient(value = &quot;CLOUD-PAYMENT-SERVICE&quot;)
public interface PaymentFeignService &#123;
    @GetMapping(value = &quot;/payment/get/&#123;id&#125;&quot;)
    public CommonResult&lt;Payment&gt; getPaymentById(@PathVariable(&quot;id&quot;) Long id);
&#125;
</code></pre>
</li>
</ol>
<ul>
<li>这里的<code>@FeignClient(value = &quot;CLOUD-PAYMENT-SERVICE&quot;)</code>调用的就是eureka中注册的两个payment服务。</li>
</ul>
</li>
<li><p>测试：</p>
<p><img src="http://cdn.rongshen2020.com/2020927a5.png"></p>
</li>
<li><p>总结：</p>
<p>feign使用默认的ribbon负载轮询算法实现负载均衡的功能。</p>
<p><img src="http://cdn.rongshen2020.com/2020927a6.png"></p>
</li>
</ol>
<h2 id="OpeFeign超时控制："><a href="#OpeFeign超时控制：" class="headerlink" title="OpeFeign超时控制："></a>OpeFeign超时控制：</h2><p><strong>OpenFeign默认等待服务端处理的时间是1秒,超过1秒,直接报错。为了避免这种情况，我们需要设置feign客户端的超时控制。</strong></p>
<p>主要在配置文件中修改：</p>
<pre><code class="java"># 设置feign客户端超时时间（openFeign默认支持ribbon）
# 一个是建立连接时间，一个是连接后到取到可用资源的时间
ribbon:
  ReadTimeout: 5000
  ConnectTimeout: 5000
</code></pre>
<p><strong>因为OpenFeign的底层是ribbon进行负载均衡,所以它的超时时间是由ribbon控制</strong></p>
<ol>
<li><p>增加下provider的controller：</p>
<pre><code class="java">@GetMapping(value = &quot;/payment/feign/timeout&quot;)
    public String paymentFeignTimeout()
    &#123;
        // 业务逻辑处理正确，但是需要耗费3秒钟
        try &#123;
            TimeUnit.SECONDS.sleep(3);
        &#125; catch (InterruptedException e) &#123;
            e.printStackTrace();
        &#125;
        return serverPort;
    &#125;
</code></pre>
</li>
<li><p>增加下consumer的controller和service：</p>
<pre><code class="java"> @GetMapping(value = &quot;/consumer/payment/feign/timeout&quot;)
    public String paymentFeignTimeout()
    &#123;
        // OpenFeign客户端一般默认等待1秒钟
        return paymentFeignService.paymentFeignTimeout();
    &#125;
</code></pre>
<pre><code class="java">@GetMapping(value = &quot;/payment/feign/timeout&quot;)
public String paymentFeignTimeout();
</code></pre>
</li>
</ol>
<ul>
<li><p>如果不写ribbon的超时控制，那么就会报错。</p>
</li>
<li><p>测试：多刷新下就会发现使用的是轮询算法。</p>
<p><img src="http://cdn.rongshen2020.com/2020927a7.png"></p>
</li>
</ul>
<h2 id="OpenFeign日志打印功能："><a href="#OpenFeign日志打印功能：" class="headerlink" title="OpenFeign日志打印功能："></a>OpenFeign日志打印功能：</h2><p>feign提供了日志打印功能，我们可以通过配置来调整日志级别，从而了解Feign中HTTP请求的细节。说白了就是对Feign接口的调用情况进行监控和输出。</p>
<p><strong>Feign的日志级别：</strong></p>
<ol>
<li>NONE：默认的，不显示任何日志。</li>
<li>BASIC：仅记录请求方法、url、响应状态码及执行时间。</li>
<li>HEADERS：除了BASIC中定义的信息之外，还有请求的和响应的头信息。</li>
<li>FULL：除了HEADERS中定义的信息之外，还有请求和响应的正文及元数据。</li>
</ol>
<h3 id="使用："><a href="#使用：" class="headerlink" title="使用："></a>使用：</h3><p><img src="http://cdn.rongshen2020.com/2020927a8.png"></p>
<ol>
<li><p>编写配置类：</p>
<pre><code class="JAVA">@Configuration
public class FeignConfig &#123;
    @Bean
    Logger.Level feignLoggerLevel()&#123;
        return Logger.Level.FULL;
    &#125;
&#125;
</code></pre>
</li>
<li><p>为指定的类设置日志级别，在配置文件中：</p>
<p><img src="http://cdn.rongshen2020.com/2020927a9.png"></p>
<pre><code class="JAVA">logging:
  level:
    com.aaron.springcloud.service.PaymentFeignService: debug
</code></pre>
</li>
<li><p>测试，那么你就可以在控制台查看：</p>
<p><img src="http://cdn.rongshen2020.com/2020927a10.png"></p>
</li>
</ol>

      
    </div>
    
    
    <div class="article-category">
      
        <b>Categories:</b>
        <a class="article-category-link" href="/categories/spring-cloud/">spring cloud</a>
      
      
        <br/>
      
      
        <b>Tags:</b>
        <a class="article-tag-none-link" href="/tags/springCloud/" rel="tag">springCloud</a>
      
    </div>
    
    
  </div>
</article>

  
<nav id="article-nav" class="article-nav">
  
    <a href="/2020/09/27/springcloud%E4%B9%8BHystrix/" id="article-nav-newer" class="article-nav-link-wrap newer">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          springcloud之Hystrix
        
      </div>
    </a>
  
  
    <a href="/2020/09/26/springcloud%E4%B9%8BRibbon/" id="article-nav-older" class="article-nav-link-wrap older">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title">
        
          springcloud之Ribbon
        
      </div>
    </a>
  
</nav>






    </div>
  </div>
  




<div id="settings-container">
  <div id="dark-mode">dark</div>
  <div id="sans-font">sans</div>
</div>
<script type="text/javascript">
let d=document,r=d.documentElement.style,f=r.setProperty.bind(r),l=localStorage,s=l.getItem('s')||(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches),n=l.getItem('n'),m=d.getElementById("dark-mode"),b=()=>{f('--bg-color','#fafafa');f('--code-bg-color','#f4f4f4');f('--text-color','#212121');f('--secondary-color','#808080');f('--tertiary-color','#b0b0b0');f('--link-color','#b5c8cf');f('--link-hover-color','#618794');f('--link-bg-color','#dae4e7');f('--selection-color','#dae4e7');m.innerHTML="dark"},c=()=>{f('--bg-color','#212121');f('--code-bg-color','#292929');f('--text-color','#fff');f('--secondary-color','#c0c0c0');f('--tertiary-color','#6e6e6e');f('--link-color','#4d6b75');f('--link-hover-color','#96b1bb');f('--link-bg-color','#5d828e');f('--selection-color','#acc1c9');m.innerHTML="light"},o=d.getElementById("sans-font"),e=()=>{f('--body-stack','"Lora", "Georgia", "Times New Roman", serif');o.innerHTML="sans"},g=()=>{f('--body-stack','"Lato", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", "Verdana", sans-serif');o.innerHTML="serif"};m.onclick=()=>{if(s==2){s=1;l.setItem('s',s);c()}else{s=2;l.setItem('s',s);b()}};o.onclick=()=>{if(n==2){n=1;l.setItem('n',n);g()}else{n=2;l.setItem('n',n);e()}};if(!s){s=2;l.setItem('s',2)};if(s==1){c()};if(!n){n=2;l.setItem('n',2)};if(n==1){g()};
</script>




</body>
</html>
